﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;
namespace Clipping.Utils
{
    public class MiniDump
    {
        internal enum MINIDUMP_TYPE
        {
            MiniDumpNormal = 0x00000000,
            MiniDumpWithDataSegs = 0x00000001,
            MiniDumpWithFullMemory = 0x00000002,
            MiniDumpWithHandleData = 0x00000004,
            MiniDumpFilterMemory = 0x00000008,
            MiniDumpScanMemory = 0x00000010,
            MiniDumpWithUnloadedModules = 0x00000020,
            MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
            MiniDumpFilterModulePaths = 0x00000080,
            MiniDumpWithProcessThreadData = 0x00000100,
            MiniDumpWithPrivateReadWriteMemory = 0x00000200,
            MiniDumpWithoutOptionalData = 0x00000400,
            MiniDumpWithFullMemoryInfo = 0x00000800,
            MiniDumpWithThreadInfo = 0x00001000,
            MiniDumpWithCodeSegs = 0x00002000
        }

        [DllImport("dbghelp.dll")]
        static extern bool MiniDumpWriteDump(
            IntPtr hProcess,
            Int32 ProcessId,
            IntPtr hFile,
            MINIDUMP_TYPE DumpType,
            IntPtr ExceptionParam,
            IntPtr UserStreamParam,
            IntPtr CallackParam);

        //[DllImport("clrdump.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        //private static extern Int32 CreateDump(Int32 ProcessId, string FileName, Int32 DumpType, Int32 ExcThreadId, IntPtr ExtPtrs);

        public static void Dump(string filePath)
        {
            string path = Path.GetDirectoryName(Path.GetFullPath(filePath));

            try
            {
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);

                using (FileStream fsToDump = File.Open(filePath, FileMode.Create))
                {
                    Process thisProcess = Process.GetCurrentProcess();
                    MiniDumpWriteDump(thisProcess.Handle, thisProcess.Id,
                        fsToDump.SafeFileHandle.DangerousGetHandle(), MINIDUMP_TYPE.MiniDumpWithIndirectlyReferencedMemory,
                        IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
                }
            }
            catch (Exception)
            {
                //忽略
            }

            //IntPtr pEP = System.Runtime.InteropServices.Marshal.GetExceptionPointers();
            //CreateDump(System.Diagnostics.Process.GetCurrentProcess().Id, filePath,
            //    (Int32)MINIDUMP_TYPE.MiniDumpWithFullMemory, AppDomain.GetCurrentThreadId(), pEP);
        }

    }

}
